package com.mornd.controller;

import com.mornd.annotation.LogStar;
import com.mornd.consts.ApiConst;
import com.mornd.consts.ResultConst;
import com.mornd.consts.ShiroConst;
import com.mornd.entity.LoginModel;
import com.mornd.entity.LoginUser;
import com.mornd.result.AjaxResult;
import com.mornd.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author mornd
 * @date 2020/12/27 - 23:42
 */
@Slf4j
@Controller
@RequestMapping("/api")
public class LoginController {
    /**
     * 获取验证码
     * @param request
     * @param response
     */
    @GetMapping("/getVerify")
    public void getVerify(HttpServletRequest request, HttpServletResponse response) throws IOException {
        CaptchaUtil.out(request,response);
    }


    /**
     * 用户登录
     * @param request
     * @param loginModel
     * @return
     */
    @LogStar("登录")
    @ResponseBody
    @PostMapping("/login")
    public Map login(HttpServletRequest request, LoginModel loginModel){
        HttpSession session = request.getSession();
        Map<String,Object> result = new AjaxResult();
        if(ObjectUtils.isEmpty(loginModel.getUsername()) || ObjectUtils.isEmpty(loginModel.getPassword())){
            result.put(ResultConst.RESULT_MESSAGE,"账号或密码不能为空");
            return result;
        }
        if(ObjectUtils.isEmpty(session)){
            result.put(ResultConst.RESULT_MESSAGE,"session超时，请刷新验证码");
            return result;
        }
        if(ObjectUtils.isEmpty(loginModel.getImgVerify())){
            result.put(ResultConst.RESULT_MESSAGE,"验证码不能为空");
            return result;
        }
        if (!CaptchaUtil.ver(loginModel.getImgVerify(), request)) {
            CaptchaUtil.clear(request);  // 清除session中的验证码
            result.put(ResultConst.RESULT_MESSAGE,"验证码错误，请重新输入");
            return result;
        }
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(loginModel.getUsername(), loginModel.getPassword());
        try {
            //执行登陆方法
            subject.login(token);
            //给shiroSession赋值
            Session shiroSession = subject.getSession();
            LoginUser loginUser = (LoginUser) subject.getPrincipal();
            shiroSession.setAttribute(ShiroConst.LOGIN_USER,loginUser);
            result.put(ResultConst.RESULT_SUCCESS,true);
            return result;
        } catch (UnknownAccountException uae) {
            result.put(ResultConst.RESULT_MESSAGE,"用户名不存在");
            return result;
        } catch (IncorrectCredentialsException ice) {
            result.put(ResultConst.RESULT_MESSAGE,"密码错误");
            return result;
        } catch (ExcessiveAttemptsException e){
            result.put(ResultConst.RESULT_MESSAGE,"登录次数过多");
            return result;
        } catch (LockedAccountException e){
            result.put(ResultConst.RESULT_MESSAGE,"该账号已被管理员锁定");
            return result;
        } catch (DisabledAccountException e){
            result.put(ResultConst.RESULT_MESSAGE,"该账号已被管理员禁用");
            return result;
        } catch (UnauthorizedException au){
            result.put(ResultConst.RESULT_MESSAGE,"您没有权限");
            return result;
        } catch (AuthenticationException e){
            result.put(ResultConst.RESULT_MESSAGE,"验证未通过");
            return result;
        } catch (Exception e){
            result.put(ResultConst.RESULT_MESSAGE,"系统异常");
            return result;
        }
    }

    /**
     * 获取当前登录用户信息
     * @return
     */
    @ResponseBody
    @RequestMapping("/getLoginUserInfo")
    public LoginUser getLoginUserInfo(){
        return (LoginUser) SecurityUtils.getSubject().getPrincipal();
    }

    /**
     * 用户注销
     * @return
     */
    @LogStar("注销")
    @RequestMapping("/logout")
    public String logout() {
        Subject subject = SecurityUtils.getSubject();
        LoginUser loginUser = (LoginUser) subject.getPrincipal();
        //清除缓存
        subject.logout();
        return "redirect:/login.html";
    }
}
